#ifndef LOAD_ELF_EXE_H

#include <elf.h>

#define BINPRM_BUF_SIZE 128
#define GEEKOS_SO "/c/asmd.so"

#define GEEKOS_SO_ROOT_PATH "/c/"

#define DYNAMIC_SCTIONG_NAME ".dynamic"
#define REL_PLT_SCTIONG_NAME ".rel.plt"
#define PLT_SCTIONG_NAME     ".plt"
#define GOT_PLT_SCTIONG_NAME ".got.plt"
#define DYNSYM_SCTIONG_NAME  ".dynsym"

#define DEFAULT_USER_STACK_SIZE 8192
#define LOAD_ELF_EXE_TEST 0

typedef	struct
{
    int num;
	char **func_name;
	Elf32_Addr	*r_offset;
}Rel_info;

typedef struct
{
	Elf32_Addr abs_offset;
	Elf32_Section Ndx;
}Exe_sym_info;

typedef	struct
{
    int num;
	char **func_name;
	Elf32_Addr	*r_offset;
	// Elf32_Word	*st_size;
}Sym_info;

int rel_sos(char **so_file_data, Elf32_Ehdr *so_ehdr, Elf32_Addr so_base_ad);

int rel_so_sh(Elf32_Shdr **shdr, int sec_num, Elf32_Addr base_ad);

int rel_so_syms(Elf32_Sym **syms, int sym_num, Elf32_Addr base_ad);

int rel_rel(Elf32_Rel **rel, int rel_num, Elf32_Addr base_ad);

int rel_so_phdrs(Elf32_Phdr **phdr, int sege_num, Elf32_Addr base_ad);

int get_exe_old_dyn_info(char *exe_file_data, Elf32_Ehdr *exe_ehdr, 
    Elf32_Shdr *exe_shdr, char *exe_strtab, Rel_info *rel_info, 
    Elf32_Addr **exe_old_sym_abs_offset);

int get_Rel_info(char *file_data, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr, 
    char *strtab, Rel_info *rel_info);

int get_exe_old_sym(char *exe_file_data, Elf32_Ehdr *exe_ehdr, 
	Elf32_Shdr *exe_shdr, char *exe_strtab, Elf32_Addr **exe_old_sym_abs_offset);

int get_dynsym_so(char *exe_file_data, Elf32_Ehdr *exe_ehdr, 
    Elf32_Shdr *exe_shdr, char *exe_strtab, char ***dynsym_so, int *cnt);

void free_dynsym_so(char ***dynsym_so, int cnt);

int share_splite(char **str, char delim);

void free_Rel_info(Rel_info *rel_info);

int get_Sym_info(char *so_file_data, Sym_info *so_sym_info);

void free_Sym_info(Sym_info *sym_info);

int rel_exe_func(char **exe_file_data, Rel_info *rel_info, Sym_info *sym_info);


// static struct User_Context* G_Create_User_Context(ulong_t size);
extern int load_elf_exe(const char *program, const char *command, 
	struct Kernel_Thread **pThread);

int get_exe_got_plt_base(Elf32_Shdr* exe_shdr, char *exe_strtab, int num, 
    Elf32_Addr *base);

int rel_exe(char **exe_file_data, Elf32_Ehdr *exe_ehdr, Elf32_Addr *exe_old_sym_abs_offset);

int rel_exe_sh(Elf32_Shdr **exe_shdr, Elf32_Addr *exe_sh_ad_ls, int num);

int rel_exe_rel(char **exe_file_data, Elf32_Shdr *exe_shdr, char *exe_strtab, 
	int num, Elf32_Addr old_got_plt_base);

int rel_exe_sym(char **exe_file_data, Elf32_Shdr *exe_shdr, int num, 
    char *exe_strtab, Elf32_Addr *old_got_plt_base);

int rel_exe_ph(Elf32_Phdr **exe_phdr, Elf32_Addr *exe_ph_ad_ls, int num);

#define LOAD_ELF_EXE_H
#endif